package com.hrsoft.edi.stub.internal;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import org.w3c.dom.Element;

import com.taobao.api.ApiException;
import com.taobao.api.internal.mapping.Converter;
import com.taobao.api.internal.mapping.Reader;
import com.taobao.api.internal.util.StringUtils;
import com.taobao.api.internal.util.XmlUtils;

public class XmlConverter implements Converter
{
    private String responseType;

    public XmlConverter(String responseType)
    {
        this.responseType = responseType;
    }

    public <T> T toResponse(String rsp, Class<T> clazz)
        throws ApiException
    {
        Element root = XmlUtils.getRootElementFromString(rsp);
        return this.getModelFromXML(root, clazz);
    }

    private <T> T getModelFromXML(final Element element, Class<T> clazz)
        throws ApiException
    {
        return element == null ? null : Converters.convert(clazz, new Reader()
        {
            public boolean hasReturnField(Object name)
            {
                Element childE = XmlUtils.getChildElement(element, (String)name);
                return childE != null;
            }

            public Object getPrimitiveObject(Object name)
            {
                return XmlUtils.getChildElementValue(element, (String)name);
            }

            public Object getObject(Object name, Class<?> type)
                throws ApiException
            {
                Element childE = XmlUtils.getChildElement(element, (String)name);
                return childE != null ? XmlConverter.this.getModelFromXML(childE, type) : null;
            }

            public List<?> getListObjects(Object listName, Object itemName, Class<?> subType)
                throws ApiException
            {
                List<Object> list = null;
                Element listE = XmlUtils.getChildElement(element, (String)listName);
                if (listE != null)
                {
                    list = new ArrayList();
                    List<Element> itemEs = XmlUtils.getChildElements(listE, (String)itemName);
                    Iterator i$ = itemEs.iterator();

                    while (i$.hasNext())
                    {
                        Element itemE = (Element)i$.next();
                        Object obj = null;
                        boolean isObject = false;
                        String value = XmlUtils.getElementValue(itemE);
                        if (String.class.isAssignableFrom(subType))
                        {
                            obj = value;
                        }
                        else if (Long.class.isAssignableFrom(subType))
                        {
                            obj = Long.valueOf(value);
                        }
                        else if (Integer.class.isAssignableFrom(subType))
                        {
                            obj = Integer.valueOf(value);
                        }
                        else if (Boolean.class.isAssignableFrom(subType))
                        {
                            obj = Boolean.valueOf(value);
                        }
                        else if (Date.class.isAssignableFrom(subType))
                        {
                            obj = StringUtils.parseDateTime(value);
                        }
                        else
                        {
                            isObject = true;
                            obj = XmlConverter.this.getModelFromXML(itemE, subType);
                        }

                        if (isObject)
                        {
                            if (obj != null)
                            {
                                list.add(obj);
                            }
                        }
                        else
                        {
                            list.add(obj);
                        }
                    }
                }

                return list;
            }
        }, this.responseType);
    }

    public String getResponseType()
    {
        return this.responseType;
    }

    public void setResponseType(String responseType)
    {
        this.responseType = responseType;
    }
}

